import datetime

from django.db.models import Q, Max
from django.http import JsonResponse
from django.shortcuts import render

from django.core.cache import cache
from django.utils.safestring import mark_safe
from django.views.decorators.csrf import csrf_exempt

from TaskSaasAPP import user_util
from TaskSaasAPP.random_util import create_random_decimal
from TaskSaasAPP.type_util import isint
from utils.pagination import Pagination
from web import models
from web.forms.breakdownstory import BreakdownStoryModelForm, StoryReplyModelForm
from web.models import BreakdownStoryType, Milestone, BreakdownStory, StoryLog, RecentTipLog, Issues
import json


class CheckFilter(object):
    """Checkbox筛选器"""

    def __init__(self, name, data_list, request):
        self.name = name
        self.data_list = sorted(data_list)
        self.request = request

    def __iter__(self):
        # print('len>>>>', len(self.data_list))
        for item in self.data_list:
            key = str(item[0])
            # print('key>>', key)
            text = item[1]
            ck = ""
            # 如果用户请求的url中status和当前key相等
            # url:xxx?status=1
            value = None
            # print('self.name in check>>>', self.name)
            value_list = self.request.GET.getlist(self.name)
            request_object = self.request.GET.get(self.name)
            if self.name == 'story_type' and request_object:
                value_list = [x for x in value_list if x != '']
                value = value_list
                # print('value list aft filter: ',value_list)
                story_type_ids = value_list
                if story_type_ids:
                    if len(value_list) > len(story_type_ids):
                        value = value_list
                    else:
                        value = story_type_ids
            elif self.name == 'story_type':
                ids_list = [str(item[0]) for item in self.data_list]
                # print('ids_list',ids_list)
                value = ids_list
            else:
                value = value_list
            # print('self.request.GET.get(self.name) >>>', value)
            query_dict = self.request.GET.copy()  # {'status',[1]}
            # if value:
            if key in value:
                ck = "checked"
                # print('key in value', ck)
                value.remove(key)  # 1,2,3:{'status',[2]}
            else:
                # print('key not in value', ck)
                value.append(key)  # 1,2,3:{'status',[2]}
            # print('value::>>',value)
            query_dict.setlist(self.name, value)  # {'status',[]}
            # 在当前url的参数上，新增参数

            if (query_dict.get('story_type')):
                pass
            elif query_dict.get('story_type') is None:
                story_type_ids = BreakdownStoryType.objects.all().values_list(
                    'id', flat=True)
                story_type_ids_as_str = [str(id_) for id_ in story_type_ids]
                query_dict.setlist('story_type', story_type_ids_as_str)
                # ck = "checked"

            query_dict._mutable = True  # 允许修改

            if 'page' in query_dict:
                query_dict.pop('page')

            if query_dict.urlencode():
                url = "{}?{}".format(self.request.path_info, query_dict.urlencode())
            else:
                url = self.request.path_info

            tpl = "<a class='cell' href='{url}'><input type='checkbox' {ck} /><label>{text}</label></a>"
            html = tpl.format(url=url, ck=ck, text=text)
            # print('html>>',html)
            yield mark_safe(html)


class SelectFilter(object):
    """Select筛选器"""

    def __init__(self, name, data_list, request):
        self.name = name
        self.data_list = data_list
        self.request = request

    def __iter__(self):
        yield mark_safe("<select class='select2' multiple='multiple' style='width:100%'>")
        for item in self.data_list:
            key = str(item[0])
            text = item[1]

            selected = ""
            # print('self.name in select>>>',self.name)
            value_list = self.request.GET.getlist(self.name)

            if key in value_list:
                selected = "selected"
                value_list.remove(key)
            else:
                value_list.append(key)

            # 在当前url的参数上，新增参数
            query_dict = self.request.GET.copy()  # {'status',[1]}
            query_dict._mutable = True  # 允许修改
            query_dict.setlist(self.name, value_list)  # {'status',[]}

            if (query_dict.get('story_type')):
                pass
            elif query_dict.get('story_type') is None:
                story_type_ids = BreakdownStoryType.objects.all().values_list(
                    'id', flat=True)
                story_type_ids_as_str = [str(id_) for id_ in story_type_ids]
                query_dict.setlist('story_type', story_type_ids_as_str)
                # selected = "selected"

            if 'page' in query_dict:
                query_dict.pop('page')

            if query_dict.urlencode():
                url = "{}?{}".format(self.request.path_info, query_dict.urlencode())
            else:
                url = self.request.path_info
            # print('url>>>',url)
            html = "<option value='{url}' {selected}>{text}</option>".format(url=url, selected=selected, text=text)
            # print('selectFilter : ',html)
            yield mark_safe(html)
            # print('html>select>>',html)
        yield mark_safe("</select>")


# 用户需求分解 用户故事
def breakdownstory(request, project_id):
    q = request.GET.get('q')
    if request.method == 'GET':
        allow_filter_name = ['module', 'story_type', 'status', 'priority', 'assign', 'attention', 'milestone_id']
        # 筛选条件(根据用户通过GET传过来的参数实现)
        condition = {}
        for name in allow_filter_name:
            print('name>>', name)
            value_list = request.GET.getlist(name)
            request_object = request.GET.get(name)
            if name == 'story_type' and request_object:
                request_object = request.GET.getlist(name)
                print('story_type in query', request_object)
                story_type_ids = request_object
                if story_type_ids:
                    print('request value_str', story_type_ids)
                    if len(value_list) > len(story_type_ids):
                        print('len(value_list) > len(story_type_ids)')
                        condition['{}__in'.format(name)] = story_type_ids
                    else:
                        condition['{}__in'.format(name)] = story_type_ids
                    continue
                else:
                    story_type_ids = list(
                        BreakdownStoryType.objects.all().values_list("id", flat=True))
                    print('else ids:', story_type_ids)
                    value_list = story_type_ids
            elif name == 'story_type':
                story_type_ids = list(
                    BreakdownStoryType.objects.all().values_list("id", flat=True))
                print('else not request_object:', story_type_ids)
                value_list = story_type_ids
            else:
                pass
                # value_list = request.GET.getlist(name)
            print('value_list of {}:'.format(name), value_list)
            if not value_list:
                continue
            condition['{}__in'.format(name)] = value_list
        # 分页获取数据
        queryset = models.BreakdownStory.objects.filter(project_id=project_id).filter(**condition).order_by('-create_datetime')
        if q:
            qq = None
            if isint(q):
                qq = Q(id=q) | Q(story_name__icontains=q)
            else:
                qq = Q(story_name__icontains=q)
            queryset = queryset.filter(qq)
        trigger = cache.get('mystoryTrigger' + str(request.web.user.id) + '_' + str(request.web.project.id), 'off')
        if trigger == 'on':
            print("trigger == 'on':")
            print(request.web.user)
            queryset = queryset.filter(Q(assign=request.web.user) | Q(attention=request.web.user)
                                       | Q(creator=request.web.user)).distinct()
        page_object = Pagination(
            current_page=request.GET.get('page'),
            all_count=queryset.count(),
            base_url=request.path_info,
            query_params=request.GET,
        )
        story_object_list = queryset[page_object.start:page_object.end]
        form = BreakdownStoryModelForm(request)
        project_total_user = [(request.web.project.creator_id, request.web.project.creator.username)]
        join_user = models.ProjectUser.objects.filter(project_id=project_id).values_list('user_id', 'user__username')
        project_total_user.extend(join_user)
        context = {
            'form': form,
            'story_object_list': story_object_list,
            'page_html': page_object.page_html(),
            'filter_list': [
                {'title': '问题类型', 'filter': CheckFilter('story_type', models.BreakdownStoryType.objects.all().values_list('id', 'title'), request)},
                {'title': '状态', 'filter': CheckFilter('status', models.BreakdownStory.status_choices, request)},
                {'title': '优先级', 'filter': CheckFilter('priority', models.BreakdownStory.priority_choices, request)},
                {'title': '指派者', 'filter': SelectFilter('assign', project_total_user, request)},
                {'title': '关注者', 'filter': SelectFilter('attention', project_total_user, request)},
            ]
        }
        return render(request, 'web/breakdownstory.html', context)
    form = BreakdownStoryModelForm(request, data=request.POST)
    # this_proj_max_story_id = models.BreakdownStory.objects.filter(project_id=request.web.project.id).aggregate(
    #     this_proj_max_story_id=Max('id'))
    # if this_proj_max_story_id:
    #     this_proj_max_story_id = this_proj_max_story_id['this_proj_max_story_id']
    #     if this_proj_max_story_id is None:
    #         this_proj_max_story_id = 0
    # else:
    #     this_proj_max_story_id = 0
    if form.is_valid():
        form.instance.project = request.web.project
        form.instance.creator = request.web.user
        # form.instance.id = this_proj_max_story_id + 1
        if form.instance.description is None or len(form.instance.description) == 0:
            form.instance.description = form.instance.story_name
        milestones = Milestone.objects.filter(project_id=project_id)
        ms2 = None
        if milestones:
            now = datetime.datetime.now().strftime("%Y-%m-%d")
            for ms in milestones:
                date_range_arr = ms.date_range.split(' - ')
                if datetime.datetime.strptime(now, "%Y-%m-%d") >= datetime.datetime.strptime(date_range_arr[0],
                                                                                             "%Y-%m-%d") and \
                        datetime.datetime.strptime(now, "%Y-%m-%d") <= datetime.datetime.strptime(date_range_arr[1],
                                                                                                  "%Y-%m-%d"):
                    ms2 = ms
                    break
        if ms2:
            form.instance.milestone = ms2
            ms2.sync_count += 1
            ms2.save()
        # 保存
        save = form.save()
        user_util.compute_forward_score(user=request.web.user, forward_score=create_random_decimal(1.00, 2.00))
        change_record = "{} 创建需求 {}".format(request.web.user.username, form.instance.story_name)
        story_log = StoryLog(story=form.instance, creator=request.web.user,
                             record=change_record,
                             log_type=1,
                             create_datetime=form.instance.create_datetime)
        story_log.save()
        recent_top_log = RecentTipLog(project=request.web.project, log_content=change_record,
                                      creator=request.web.user,type=4,relation_data_id=save.id,
                                      log_url='/manage/{}/breakdownstory/detail/{}'.format(project_id, save.id))
        recent_top_log.save()
        return JsonResponse({'status': True, })
    return JsonResponse({'status': False, 'error': form.errors})


def story_del(request, project_id):
    story_id = request.POST.get('story_id')
    story = BreakdownStory.objects.filter(id=story_id).first()
    if story:
        story.delete()
        RecentTipLog.objects.filter(project__id=project_id, type=4, relation_data_id=story_id).delete()
        return JsonResponse({'status': 1})
    return JsonResponse({'status': 0})


def story_detail(request, project_id, story_id):
    story = models.BreakdownStory.objects.filter(id=story_id, project_id=project_id).first()
    form = BreakdownStoryModelForm(request, instance=story)
    child_object_list = None
    story_child_list = None
    if story:
        child_object_list = BreakdownStory.objects.filter(parent_id=story.id, project=request.web.project)\
            .values_list('id', 'story_name')
        story_child_list = Issues.objects.filter(parent_story=story,project=request.web.project).values_list('issue_id','subject')
    context = {
        'id': story_id,
        'form': form,
        'story_object': story,
        'child_list': child_object_list,
        'story_child_list': story_child_list
    }
    return render(request, 'web/story_detail.html', context)


@csrf_exempt
def story_change(request, project_id, story_id):
    """表单更新数据"""
    story_object = models.BreakdownStory.objects.filter(id=story_id, project_id=project_id).first()
    post_dict = json.loads(request.body.decode('utf-8'))
    # 数据库字段更新
    name = post_dict.get('name')
    value = post_dict.get('value')
    field_object = models.BreakdownStory._meta.get_field(name)

    def create_reply_record(change_record):
        new_object = models.StoryReply.objects.create(
            reply_type=1,
            story=story_object,
            content=change_record,
            creator=request.web.user
        )
        success = None
        if new_object.id:
            success = True
        new_reply_dict = {
            'status': success,
            'id': new_object.id,
            'reply_type_text': new_object.get_reply_type_display(),
            'content': new_object.content,
            'creator': new_object.creator.username,
            'datetime': new_object.create_datetime.strftime("%Y-%m-%d %H:%M"),
            'parent_id': new_object.reply_id
        }
        return new_reply_dict
    print('name:{}'.format(name))
    # 文本内容
    if name in ['story_name', 'description', 'start_date', 'end_date','version']:
        if not value:
            print('not value>>', value)
            if not field_object.null:
                return JsonResponse({'status': False, 'error': '您选择的值不能为空！'})
            setattr(story_object, name, None)
            story_object.save()
            user_util.compute_forward_score(user=request.web.user, forward_score=create_random_decimal(0.01, 0.06))
            # 记录
            change_record = "{} 更新为空".format(field_object.verbose_name)
            print('change_record:',change_record)
            story_log = StoryLog(story=story_object, creator=request.web.user,
                                 record=change_record,
                                 create_datetime=story_object.latest_update_datetime)
            story_log.save()
        else:
            print('change name:', name)
            if name == 'start_date':
                print('.>>>>>>>start_date')
                ms = story_object.milestone
                if ms:
                    date_range_arr = ms.date_range.split(' - ')
                # print("date_range_arr>>",date_range_arr)
                    if datetime.datetime.strptime(value, "%Y-%m-%d") >= datetime.datetime.strptime(date_range_arr[0],
                                                                                                   "%Y-%m-%d") and \
                            datetime.datetime.strptime(value, "%Y-%m-%d") <= datetime.datetime.strptime(date_range_arr[1],
                                                                                                        "%Y-%m-%d"):
                        pass
                else:
                    milestones = Milestone.objects.filter(project_id=project_id)
                    ms2 = None
                    if milestones:
                        for ms in milestones:
                            date_range_arr = ms.date_range.split(' - ')
                            if datetime.datetime.strptime(value, "%Y-%m-%d") >= datetime.datetime.strptime(
                                    date_range_arr[0], "%Y-%m-%d") and \
                                    datetime.datetime.strptime(value, "%Y-%m-%d") <= datetime.datetime.strptime(
                                date_range_arr[1], "%Y-%m-%d"):
                                ms2 = ms
                                break
                    if ms2:
                        story_object.milestone = ms2
                        ms2.sync_count += 1
                        ms2.save()
            setattr(story_object, name, value)
            story_object.save()
            user_util.compute_forward_score(user=request.web.user, forward_score=create_random_decimal(0.01, 0.06))
            # 记录
            if name == 'version':
                value = dict(BreakdownStory.version_choices).get(int(value))
            change_record = "{} 更新为 {}".format(field_object.verbose_name, value)
            story_log = StoryLog(story=story_object, creator=request.web.user,
                                 record=change_record,
                                 create_datetime=story_object.latest_update_datetime)
            story_log.save()

        return JsonResponse({'status': True, 'data': create_reply_record(change_record)})

    # FKEY对象
    if name in ['story_type', 'module', 'assign', 'parent','milestone']:
        print('value>>',value)
        if not value:
            if not field_object.null:
                return JsonResponse({'status': False, 'error': '您选择的值不能为空！'})
            setattr(story_object, name, None)
            story_object.save()
            user_util.compute_forward_score(user=request.web.user, forward_score=create_random_decimal(0.01, 0.06))
            # 记录
            change_record = "{} 更新为空 ".format(field_object.verbose_name)
            story_log = StoryLog(story=story_object, creator=request.web.user,
                                 record=change_record,
                                 create_datetime=story_object.latest_update_datetime)
            story_log.save()
        else:
            if name == 'assign':
                if value == str(request.web.project.creator_id):
                    instance = request.web.project.creator
                else:
                    project_user_object = models.ProjectUser.objects.filter(project_id=project_id,
                                                                            user_id=value).first()
                    if project_user_object:
                        instance = project_user_object.user
                    else:
                        instance = None
                if not instance:
                    return JsonResponse({'status': False, 'error': '您选择的值不存在！'})
            else:
                print('用户输入的值是自己的值value:', value)
                # 用户输入的值是自己的值
                instance = field_object.remote_field.model.objects.filter(id=value).first()
                if not instance:
                    return JsonResponse({'status': False, 'error': '您选择的值不存在！'})
            user_util.compute_forward_score(user=request.web.user, forward_score=create_random_decimal(0.01, 0.06))
            change_record = "{} 更新为 {}".format(field_object.verbose_name, str(instance))
            setattr(story_object, name, instance)
            story_object.save()
            story_log = StoryLog(story=story_object, creator=request.web.user,
                                 record=change_record,
                                 create_datetime=story_object.latest_update_datetime)
            story_log.save()
        return JsonResponse({'status': True, 'data': create_reply_record(change_record)})
    # choice字段
    if name in [ 'status', 'priority']:
        seleted_text = None
        for key, text in field_object.choices:
            if str(key) == value:
                seleted_text = text
        if not seleted_text:
            return JsonResponse({'status': False, 'error': '您选择的值不存在！'})
        setattr(story_object, name, value)
        story_object.save()
        user_util.compute_forward_score(user=request.web.user, forward_score=create_random_decimal(0.01, 0.06))
        change_record = "{} 更新为 {}".format(field_object.verbose_name, seleted_text)
        story_log = StoryLog(story=story_object, creator=request.web.user,
                             record=change_record,
                             create_datetime=story_object.latest_update_datetime)
        story_log.save()
        if name in ['status']:
            print('name in status', )
            if value == '5':
                using_time_delta = datetime.datetime.now() - story_object.create_datetime
                using_time_str = "{}天-{}小时-{}分钟-{}秒".format(using_time_delta.days,
                                                                  (using_time_delta.seconds // 3600),
                                                                  ((using_time_delta.seconds % 3600) // 60),
                                                                  using_time_delta.seconds % 60)
                story_object.using_time = using_time_str
                story_object.save()
                user_util.compute_forward_score(user=request.web.user, forward_score=create_random_decimal(0.01, 0.06))
            else:
                if story_object.using_time:
                    story_object.using_time = None
                    story_object.save()
                    user_util.compute_forward_score(user=request.web.user,
                                                    forward_score=create_random_decimal(0.01, 0.06))
        return JsonResponse({'status': True, 'data': create_reply_record(change_record)})
    if name in ['iteration_number','acceptance_criteria']:
        if name == 'iteration_number' and not isint(value):
            return JsonResponse({'status': False, 'error': '您选择的值格式错误！'})
        setattr(story_object, name, value)
        story_object.save()
        user_util.compute_forward_score(user=request.web.user,
                                        forward_score=create_random_decimal(0.01, 0.06))
        change_record = "{} 更新为 {}".format(field_object.verbose_name, value)
        story_log = StoryLog(story=story_object, creator=request.web.user,
                             record=change_record,
                             create_datetime=story_object.latest_update_datetime)
        story_log.save()
        return JsonResponse({'status': True, 'data': create_reply_record(change_record)})
    # M2M字段
    if name in ['attention']:

        # {'name':'abc','value':[1,2,3]}
        # if not isinstance(value, list):
        #     return JsonResponse({'status': False, 'error': '数据格式错误！'})

        if not value:
            story_object.attention.set([])
            story_object.save()
            change_record = "{} 更新为空".format(field_object.verbose_name)
            story_log = StoryLog(story=story_object, creator=request.web.user,
                                 record=change_record,
                                 create_datetime=story_object.latest_update_datetime)
            user_util.compute_forward_score(user=request.web.user,
                                            forward_score=create_random_decimal(0.01, 0.03))
            story_log.save()
        else:
            # values=[1,2,3,4] 参与者/创建者
            # 获取当前项目所有成员
            user_dict = {str(request.web.project.creator_id): request.web.project.creator.username}
            project_user_list = models.ProjectUser.objects.filter(project_id=project_id)

            # 将项目成员全放入user_dict
            for item in project_user_list:
                user_dict[str(item.user_id)] = item.user.username
            username_list = []
            for user_id in value:
                username = user_dict.get(user_id)
                if not username:
                    return JsonResponse({'status': False, 'error': '数据错误！'})
                username_list.append(username)

            story_object.attention.set(value)
            story_object.save()
            user_util.compute_forward_score(user=request.web.user,
                                            forward_score=create_random_decimal(0.01, 0.06))
            change_record = "{} 更新为 {}".format(field_object.verbose_name, ",".join(username_list))
            story_log = StoryLog(story=story_object, creator=request.web.user,
                                 record=change_record,
                                 create_datetime=story_object.latest_update_datetime)
            story_log.save()
        return JsonResponse({'status': True, 'data': create_reply_record(change_record)})

    return JsonResponse({'status': False, 'error': 'Error！'})


@csrf_exempt
def story_record(request, project_id, story_id):
    print('story_record invoke',story_id)
    """初始化操作记录"""
    if request.method == 'GET':
        reply_list = models.StoryReply.objects.filter(story_id=story_id, story__project=request.web.project).order_by(
            'create_datetime')
        print('reply_list',reply_list)
        # 将queryset转换为json格式
        data_list = []
        for row in reply_list:
            data = {
                'id': row.id,
                'reply_type_text': row.get_reply_type_display(),
                'content': row.content,
                'creator': row.creator.username,
                'datetime': row.create_datetime.strftime("%Y-%m-%d %H:%M"),
                'parent_id': row.reply_id
            }
            data_list.append(data)
        return JsonResponse({'status': True, 'data': data_list})
    form = StoryReplyModelForm(data=request.POST)
    print('post:', request.POST)
    if form.is_valid():
        # 这里不要动就好，这里id=pk就是没问题的，虽然在数据库字段是issues_pk，但instance的不是
        form.instance.story_id = story_id
        form.instance.reply_type = 2
        form.instance.creator = request.web.user
        form.instance.create_datetime = datetime.datetime.now()
        instance = form.save()
        info = {
            'id': instance.id,
            'reply_type_text': instance.get_reply_type_display(),
            'content': instance.content,
            'creator': instance.creator.username,
            'datetime': instance.create_datetime.strftime("%Y-%m-%d %H:%M"),
            'parent_id': instance.reply_id
        }
        return JsonResponse({'status': True, 'data': info})
    return JsonResponse({'status': False, 'error': form.errors})
